package register

import (
	"context"
	"go.etcd.io/etcd/clientv3"
	"time"
	"fmt"
)

/**
服务注册：
将各微服务ip,port 以key,value形式注册进入etcd
 */

type Register struct {
	clientv3 *clientv3.Client
	key string
	serverAddress string
	interval time.Duration //心跳间隔(每隔x秒put key到etcd)
	leaseTime int64  //租赁时间(到期etcd自动删除指定的key)
	stop chan bool //判断服务是否挂掉或断开或其他不可用状态(此时去etcd里删除相应key)
}

func New(clientv3 *clientv3.Client,key string,serverAddress string)*Register{
	return &Register{
		clientv3:clientv3,
		key:key,
		serverAddress:serverAddress,
		interval:10 * time.Second,
		leaseTime:15,
		stop:make(chan bool),
	}
}

//服务注册
func (r *Register)RegisterServer(){
	go func() {
		t := time.NewTicker(r.interval)
		for {
			//将服务地址put入etcd
			lgr,err := r.clientv3.Grant(context.TODO(),r.leaseTime)//创建一个新租赁
			if err!=nil{
				panic(err)
			}
			_,err = r.clientv3.Get(context.TODO(),r.makekey())
			if err!=nil{
				fmt.Println(r.makekey()+"服务获取失败！")
			}else {
				_,err := r.clientv3.Put(context.TODO(),r.makekey(),r.serverAddress,clientv3.WithLease(lgr.ID))//使用lease租赁方式存储值
				if err!=nil{
					panic(err)
				}else {
					fmt.Println(r.makekey()+"服务注册成功")
				}
			}
			select {
			case ttl := <-t.C:
				fmt.Println(ttl)
			case <-r.stop:
				//将服务地址从etcd删除
				_,err := r.clientv3.Delete(context.TODO(),r.makekey())
				if err!=nil{
					panic(err)
				}else {
					fmt.Println(r.makekey()+"服务删除成功!")
					return //跳出循环
				}
			}
		}
	}()
}
//服务注销
func (r *Register)UnRegisterServer(){
	r.stop <- true
}

//etcd key自定义
func (r *Register)makekey()string{
	return fmt.Sprintf("%s_%s",r.key,r.serverAddress)
}
func (r *Register)ServerAddress()string{
	return r.serverAddress
}